package npap.cater.unr.edu.client.scaffold.place;

import npap.cater.unr.edu.client.managed.request.ApplicationRequestFactory;
import npap.cater.unr.edu.client.proxy.ProjectProxy;
import npap.cater.unr.edu.client.scaffold.place.ProxyPlace.Operation;
import npap.cater.unr.edu.client.scaffold.place.customized.AppPlace;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.ui.HasConstrainedValue;
import com.google.web.bindery.requestfactory.shared.Receiver;

/**
 * Drives a {@link ValueChangeHandler} populated with {@link ProxyListPlace}
 * instances, keeping it in sync with the {@link PlaceController}'s notion of
 * the current place, and firing place change events as selections are made.
 */
public class ProxyListPlacePicker implements ValueChangeHandler<ProxyListPlace>, PlaceChangeEvent.Handler {
	/**
	 * @uml.property  name="view"
	 * @uml.associationEnd  
	 */
	private HasConstrainedValue<ProxyListPlace> view;
	/**
	 * @uml.property  name="placeController"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private final PlaceController placeController;
	/**
	 * @uml.property  name="proxyPlaceToListPlace"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private final ProxyPlaceToListPlace proxyPlaceToListPlace;
	/**
	 * @uml.property  name="requests"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private final ApplicationRequestFactory requests;

	public ProxyListPlacePicker(PlaceController placeController, ProxyPlaceToListPlace proxyPlaceToListPlace, ApplicationRequestFactory requests) {
		this.placeController = placeController;
		this.proxyPlaceToListPlace = proxyPlaceToListPlace;
		this.requests=requests;
	}

	public void onPlaceChange(PlaceChangeEvent event) {
		if(event.getNewPlace() instanceof AppPlace)
		{

			view.setValue(proxyPlaceToListPlace.proxyListPlaceFor(event.getNewPlace()), false);

		}else
		{
			return;

		}
		
		
	}

	public void onValueChange(ValueChangeEvent<ProxyListPlace> event) {
		ProxyListPlace newPlace=event.getValue();
		Place currentPlace=placeController.getWhere();
		if(currentPlace instanceof AppPlace)
		{
			final AppPlace currentAppPlace=(AppPlace) currentPlace;
			if(newPlace.getProxyClass().equals(ProjectProxy.class))
			{
				requests.projectRequest()
				.findProject(currentAppPlace.getProjectID())
				.fire(new Receiver<ProjectProxy>() {

					@Override
					public void onSuccess(ProjectProxy response) {
						// TODO Auto-generated method stub
						AppPlace appPlace = new AppPlace(response.stableId(),
								Operation.DETAILS, currentAppPlace.getProjectID(), currentAppPlace
										.getProjectName());
						placeController.goTo(appPlace);
					}

				});
			}else{
				placeController.goTo(new AppPlace(newPlace.getProxyClass(), Operation.LIST, currentAppPlace.getProjectID(), currentAppPlace.getProjectName()));
			}
			
		}
		
	}

	public HandlerRegistration register(EventBus eventBus, HasConstrainedValue<ProxyListPlace> view) {
		this.view = view;
		final HandlerRegistration placeRegistration = eventBus.addHandler(PlaceChangeEvent.TYPE, this);
		final HandlerRegistration viewRegistration = view.addValueChangeHandler(this);

		return new HandlerRegistration() {
			public void removeHandler() {
				placeRegistration.removeHandler();
				viewRegistration.removeHandler();
				ProxyListPlacePicker.this.view = null;
			}
		};
	}

	
}
